from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from django.contrib.auth.decorators import login_required
from django.db import transaction
from django.db.models import Q
from django.utils import timezone
from decimal import Decimal
import json
from backed.cos_utils import cos_uploader
from .models import ExchangeItem, ExchangeTransaction
import math


def _paginate(queryset, page, page_size):
    try:
        page = int(page or 1)
        page_size = int(page_size or 10)
    except Exception:
        page, page_size = 1, 10
    total = queryset.count()
    start = (page - 1) * page_size
    end = start + page_size
    return queryset[start:end], {'page': page, 'page_size': page_size, 'total': total}


@csrf_exempt
@require_http_methods(["GET", "POST"])
def items_view(request):
    if request.method == "GET":
        try:
            qs = ExchangeItem.objects.all()
            status = request.GET.get('status')
            category = request.GET.get('category')
            city = request.GET.get('city')
            q = request.GET.get('q')
            offer_type = request.GET.get('offer_type')
            if status:
                qs = qs.filter(status=status)
            if category:
                qs = qs.filter(category=category)
            if city:
                qs = qs.filter(city=city)
            if q:
                qs = qs.filter(Q(title__icontains=q) | Q(description__icontains=q))
            if offer_type:
                qs = qs.filter(offer_type=offer_type)
            page_qs, meta = _paginate(qs.order_by('-created_at', 'item_id'), request.GET.get('page'), request.GET.get('page_size'))
            allowed_categories = [c[0] for c in ExchangeItem.CATEGORY_CHOICES]
            cat_counts = {k: 0 for k in allowed_categories}
            for c in qs.values_list('category', flat=True):
                k = c or '其他'
                if k in cat_counts:
                    cat_counts[k] += 1
            cat_stats = [{'name': k, 'count': cat_counts[k]} for k in allowed_categories]
            def haversine(lat1,lng1,lat2,lng2):
                R=6371000.0
                phi1=math.radians(lat1); phi2=math.radians(lat2)
                dphi=math.radians(lat2-lat1); dlambda=math.radians(lng2-lng1)
                a=math.sin(dphi/2)**2+math.cos(phi1)*math.cos(phi2)*math.sin(dlambda/2)**2
                c=2*math.atan2(math.sqrt(a),math.sqrt(1-a)); return R*c
            u_lat = getattr(getattr(request.user, 'profile', None), 'lat', None)
            u_lng = getattr(getattr(request.user, 'profile', None), 'lng', None)
            data = [{
                'item_id': i.item_id,
                'title': i.title,
                'description': i.description,
                'image_url': i.image_url,
                'category': i.category,
                'city': i.city,
                'offer_type': i.offer_type,
                'lat': i.lat,
                'lng': i.lng,
                'status': i.status,
                'created_at': i.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                'provider_username': (getattr(i.user, 'username', None) if i.user else None),
                'provider_nickname': (getattr(getattr(i.user, 'profile', None), 'nickname', None) if i.user else None),
                'provider_avatar_url': (getattr(getattr(i.user, 'profile', None), 'avatar', None) if i.user else None),
                'provider_phone': (getattr(getattr(i.user, 'profile', None), 'phone', None) if i.user else None),
                'provider_email': (getattr(i.user, 'email', None) if i.user else None),
                'distance_km': (round(haversine(float(u_lat), float(u_lng), float(i.lat), float(i.lng))/1000.0, 3) if (u_lat is not None and u_lng is not None and i.lat is not None and i.lng is not None) else None)
            } for i in page_qs]
            return JsonResponse({'success': True, 'data': {'items': data, 'meta': meta, 'categories': allowed_categories, 'stats': cat_stats}})
        except Exception as e:
            return JsonResponse({'success': False, 'message': str(e)}, status=500)
    if request.method == "POST":
        try:
            if not request.user.is_authenticated:
                return JsonResponse({'success': False, 'message': '未登录'}, status=401)
            title = request.POST.get('title') or None
            description = request.POST.get('description') or None
            category = request.POST.get('category') or None
            city = request.POST.get('city') or None
            offer_type = request.POST.get('offer_type') or 'exchange'
            lat = request.POST.get('lat')
            lng = request.POST.get('lng')
            image_url = request.POST.get('image_url') or None
            uploaded_url = None
            if 'image' in request.FILES:
                upload_result = cos_uploader.upload_file(request.FILES['image'], file_type='exchange', user_id=request.user.id)
                if not upload_result['success']:
                    return JsonResponse({'success': False, 'message': upload_result['message']}, status=500)
                uploaded_url = upload_result['url']
            final_image_url = uploaded_url or image_url
            if not title or not final_image_url:
                return JsonResponse({'success': False, 'message': '缺少必填参数'}, status=400)
            if category:
                allowed_categories = [c[0] for c in ExchangeItem.CATEGORY_CHOICES]
                if category not in allowed_categories:
                    return JsonResponse({'success': False, 'message': '分类不在可选范围'}, status=400)
            if city:
                allowed_cities = [c[0] for c in ExchangeItem.CITY_CHOICES]
                if city not in allowed_cities:
                    return JsonResponse({'success': False, 'message': '城市不在可选范围'}, status=400)
            if offer_type:
                allowed_types = [t[0] for t in ExchangeItem.OFFER_TYPE_CHOICES]
                if offer_type not in allowed_types:
                    return JsonResponse({'success': False, 'message': '类型不在可选范围'}, status=400)
            try:
                lat = float(lat) if lat is not None else None
                lng = float(lng) if lng is not None else None
            except (TypeError, ValueError):
                lat = None; lng = None
            item = ExchangeItem.objects.create(
                user=request.user,
                title=title,
                description=description,
                image_url=final_image_url,
                category=category,
                city=city,
                offer_type=offer_type,
                lat=lat,
                lng=lng,
                status='available'
            )
            return JsonResponse({'success': True, 'message': '发布成功', 'data': {
                'item_id': item.item_id,
                'title': item.title,
                'description': item.description,
                'image_url': item.image_url,
                'category': item.category,
                'city': item.city,
                'offer_type': item.offer_type,
                'status': item.status,
                'created_at': item.created_at.strftime('%Y-%m-%d %H:%M:%S')
            }}, status=201)
        except Exception as e:
            return JsonResponse({'success': False, 'message': str(e)}, status=500)


@csrf_exempt
@require_http_methods(["GET", "DELETE"])
def item_detail_view(request, item_id):
    try:
        item = ExchangeItem.objects.get(item_id=item_id)
    except ExchangeItem.DoesNotExist:
        return JsonResponse({'success': False, 'message': '物品不存在'}, status=404)
    if request.method == "GET":
        return JsonResponse({'success': True, 'data': {
            'item_id': item.item_id,
            'title': item.title,
            'description': item.description,
            'image_url': item.image_url,
            'category': item.category,
            'city': item.city,
            'offer_type': item.offer_type,
            'lat': item.lat,
            'lng': item.lng,
            'status': item.status,
            'created_at': item.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'provider_user_id': item.user.id if item.user else None,
            'provider_username': item.user.username if item.user else None
        }})
    if request.method == "DELETE":
        if not request.user.is_authenticated:
            return JsonResponse({'success': False, 'message': '未登录'}, status=401)
        if (item.user and item.user != request.user) and (not request.user.is_staff):
            return JsonResponse({'success': False, 'message': '无权限'}, status=403)
        item.delete()
        return JsonResponse({'success': True, 'message': '删除成功'})


@csrf_exempt
@require_http_methods(["PATCH"]) 
def update_status_view(request, item_id):
    try:
        item = ExchangeItem.objects.get(item_id=item_id)
    except ExchangeItem.DoesNotExist:
        return JsonResponse({'success': False, 'message': '物品不存在'}, status=404)
    try:
        if not request.user.is_authenticated:
            return JsonResponse({'success': False, 'message': '未登录'}, status=401)
        if (item.user and item.user != request.user) and (not request.user.is_staff):
            return JsonResponse({'success': False, 'message': '无权限'}, status=403)
        data = json.loads(request.body or '{}')
        status = data.get('status')
        if status not in ['available', 'exchanged']:
            return JsonResponse({'success': False, 'message': '状态不合法'}, status=400)
        with transaction.atomic():
            item.status = status
            item.save()
        return JsonResponse({'success': True, 'message': '状态更新成功', 'data': {'item_id': item.item_id, 'status': item.status}})
    except json.JSONDecodeError:
        return JsonResponse({'success': False, 'message': '无效的JSON'}, status=400)
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)}, status=500)


@csrf_exempt
@require_http_methods(["POST"]) 
def transactions_view(request):
    try:
        if not request.user.is_authenticated:
            return JsonResponse({'success': False, 'message': '未登录'}, status=401)
        data = json.loads(request.body or '{}')
        item_id = data.get('item_id')
        if not item_id:
            return JsonResponse({'success': False, 'message': '缺少item_id'}, status=400)
        try:
            with transaction.atomic():
                item = ExchangeItem.objects.select_for_update().get(item_id=item_id)
                if item.status != 'available':
                    return JsonResponse({'success': False, 'message': '物品状态不可交易'}, status=400)
                provider = item.user
                receiver = request.user
                if provider is None:
                    return JsonResponse({'success': False, 'message': '物品缺少发布者信息'}, status=400)
                tx = ExchangeTransaction.objects.create(item=item, provider=provider, receiver=receiver)
                item.status = 'exchanged'
                item.save()
        except ExchangeItem.DoesNotExist:
            return JsonResponse({'success': False, 'message': '物品不存在'}, status=404)
        return JsonResponse({'success': True, 'message': '交易创建成功', 'data': {
            'transaction_id': tx.transaction_id,
            'item_id': item.item_id,
            'provider_user_id': provider.id if provider else None,
            'receiver_user_id': receiver.id,
            'completed_at': tx.completed_at.strftime('%Y-%m-%d %H:%M:%S'),
            'status': item.status
        }}, status=201)
    except json.JSONDecodeError:
        return JsonResponse({'success': False, 'message': '无效的JSON'}, status=400)
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)}, status=500)


@csrf_exempt
@require_http_methods(["GET"]) 
@login_required
def my_items_view(request):
    try:
        qs = ExchangeItem.objects.filter(user=request.user)
        page_qs, meta = _paginate(qs.order_by('-created_at', 'item_id'), request.GET.get('page'), request.GET.get('page_size'))
        data = [{
            'item_id': i.item_id,
            'title': i.title,
            'description': i.description,
            'image_url': i.image_url,
            'category': i.category,
            'city': i.city,
            'offer_type': i.offer_type,
            'status': i.status,
            'created_at': i.created_at.strftime('%Y-%m-%d %H:%M:%S')
        } for i in page_qs]
        return JsonResponse({'success': True, 'data': {'items': data, 'meta': meta}})
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)}, status=500)


@csrf_exempt
@require_http_methods(["POST"]) 
@login_required
def upload_exchange_image(request):
    try:
        if 'image' not in request.FILES:
            return JsonResponse({'success': False, 'message': '请选择要上传的图片文件'}, status=400)
        image_file = request.FILES['image']
        allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']
        max_size = 10 * 1024 * 1024
        if image_file.content_type not in allowed_types:
            return JsonResponse({'success': False, 'message': '只支持JPEG、PNG、GIF、WebP格式的图片'}, status=400)
        if image_file.size > max_size:
            return JsonResponse({'success': False, 'message': '图片文件大小不能超过10MB'}, status=400)
        upload_result = cos_uploader.upload_file(image_file, file_type='exchange', user_id=request.user.id)
        if not upload_result.get('success'):
            return JsonResponse({'success': False, 'message': upload_result.get('message', '上传失败')}, status=500)
        return JsonResponse({'success': True, 'message': '图片上传成功', 'data': {'image_url': upload_result['url'], 'image_path': upload_result['path']}})
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)}, status=500)

# Create your views here.
